package com.example.netty;

import com.example.mqtt.MqttClientConnect;
import com.example.util.ConvertCode;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {

    //定义一个channle 组，管理所有的channel
    //GlobalEventExecutor.INSTANCE) 是全局的事件执行器，是一个单例
    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 有客户端与服务器发生连接时执行此方法
     * 1.打印提示信息
     * 2.将客户端保存到 channelGroup 中
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.err.println("有新的 Client 与 Server发生连接。客户端地址：" + channel.remoteAddress());
        channelGroup.add(channel);
        // 将通道加入ChannelMap
        ChannelMap.getChannelMap().put(String.valueOf(ctx.channel().id()), ctx.channel());
    }

    /**
     * 当有客户端与服务器断开连接时执行此方法，此时会自动将此客户端从 channelGroup 中移除
     * 1.打印提示信息
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.err.println("有 Client 与 Server 断开连接。客户端地址：" + channel.remoteAddress());
    }

    /**
     * 表示channel 处于活动状态
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + " 处于活动状态");
    }

    /**
     * 表示channel 处于不活动状态
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + " 处于不活动状态");
        // map中移除channel
        removeId(ctx);
    }

    /**
     * 读取到客户端发来的数据数据
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //获取到当前channel
        Channel channel = ctx.channel();
        System.err.println(df.format(new Date()) + " 有 Client " + channel.id() + " 发来的数据。地址：" + channel.remoteAddress() + " 内容：" + msg);

        byte[] bytes = msg.getBytes();
        // 将接收到的数据转为字符串，此字符串就是客户端发送的字符串
        String receiveStr = ConvertCode.receiveHexToString(bytes);

        System.err.println("转化 16 进制数据 ："  + receiveStr);
        /*处理16进制数据方法*/
        getAiFromHex(receiveStr, channel.remoteAddress().toString());
    }

    /**
     * 处理异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("发生异常。异常信息：{}", cause.getMessage());
        // map中移除channel
        removeId(ctx);
        //关闭通道
        ctx.close();
    }


    private void removeId(ChannelHandlerContext ctx) {
        AttributeKey<String> key = AttributeKey.valueOf("id");
        // 获取channel中id
        String id = ctx.channel().id().toString();
        // map移除channel
        ChannelMap.getChannelMap().remove(id);
    }

    // 处理有人云16进制数据方法
    private static void getAiFromHex(String hexStr, String address) {
        try {
            if(hexStr.length()>=30){
                //获取 16进制位电流值
                // 字符串的 第27位 ~ 30 位代表数值
                String aiVal = hexStr.substring(26,30);
                Double bits = (double) Long.parseLong(aiVal, 16);
                Double aiValdou = bits/1000;
                System.out.println( "字符串的 16 进制数组 : " + aiVal + " 转换后为 : " + aiValdou +"mA");
                /** 处理不同IO串口服务器的电流误差
                 * 137 服务器大0.007mA
                 * 141 服务器大0.024mA
                 * 241 服务器大0.007mA
                 * 249 服务器大0.024mA
                 * */
                if(address.contains("137") || address.contains("241")){
                    aiValdou = aiValdou - 0.007;
                }else if(address.contains("141") || address.contains("249")){
                    aiValdou = aiValdou - 0.024;
                }
                /** 通过电流获取潮位仪高度
                 * 高度=（电流值-4）/4
                 * */
                Double high = (aiValdou -4)/4;
                DecimalFormat df = new DecimalFormat("#.##");
                String highStr = df.format(high);
                System.out.println("ip地址是 " + address + " 的电流值： " + aiValdou + " ,潮位高度: " + highStr);

                /* 发送模拟数据到mqtt */
//                ConcurrentHashMap<String, MqttClientConnect> mqttClients = MqttClientConnect.mqttClients;
//                MqttClientConnect mqttClientConnect = mqttClients.get("1");
//                mqttClientConnect.pub("seaLevel", highStr);

            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        String msg = "77 77 77 2E 75 73 72 2E 63 6E 11 03 02 00 00 79 87";
        byte[] bytes = msg.getBytes();
        // 将接收到的数据转为字符串，此字符串就是客户端发送的字符串
        String receiveStr = ConvertCode.receiveHexToString(bytes);

        System.err.println("转化 16 进制数据 ："  + receiveStr);
        getAiFromHex(receiveStr,"192.138.0.143");
    }
}
